1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
// (1) next-auth에서 필요한 타입들을 import
import NextAuth, {
NextAuthOptions, // authOptions에 쓸 타입
Session,
User
} from 'next-auth'
import { JWT } from "next-auth/jwt"
import CredentialsProvider from 'next-auth/providers/credentials'
import { verifyOtp } from '@/lib/users/verifyOtp'
// 1) 모듈 보강 선언
declare module "next-auth" {
/**
* Session 객체를 확장
*/
interface Session {
user: {
/** 우리가 필요로 하는 user id */
id: string
// 기본적으로 NextAuth가 제공하는 name/email/image 필드
name?: string | null
email?: string | null
image?: string | null
companyId?: number | null
domain?: string | null
}
}
/**
* User 객체를 확장
*/
interface User {
id: string
imageUrl?: string | null
companyId?: number | null
domain?: string | null
// 필요한 필드를 추가로 선언 가능
}
}
// (2) authOptions에 NextAuthOptions 타입 지정
export const authOptions: NextAuthOptions = {
providers: [
CredentialsProvider({
name: 'Credentials',
credentials: {
email: { label: 'Email', type: 'text' },
code: { label: 'OTP code', type: 'text' },
},
async authorize(credentials, req) {
const { email, code } = credentials ?? {}
// OTP 검증
const user = await verifyOtp(email ?? '', code ?? '')
if (!user) {
return null
}
return {
id: String(user.id ?? email ?? "dts"),
email: user.email,
imageUrl: user.imageUrl ?? null,
name: user.name, // DB에서 가져온 실제 이름
companyId: user.companyId, // DB에서 가져온 실제 이름
domain: user.domain, // DB에서 가져온 실제 이름
}
},
})
],
// (3) session.strategy는 'jwt'가 되도록 선언
// 필요하다면 as SessionStrategy 라고 명시해줄 수도 있음
// 예) strategy: 'jwt' as SessionStrategy
session: {
strategy: 'jwt',
},
callbacks: {
// (4) 콜백에서 token, user, session 등의 타입을 좀 더 명시해주고 싶다면 아래처럼 destructuring에 제네릭/타입 지정
async jwt({ token, user }: { token: JWT; user?: User }) {
if (user) {
token.id = user.id
token.email = user.email
token.name = user.name
token.companyId = user.companyId
token.domain = user.domain
; (token as any).imageUrl = (user as any).imageUrl
}
return token
},
async session({ session, token }: { session: Session; token: JWT }) {
if (token) {
session.user = {
id: token.id as string,
email: token.email as string,
name: token.name as string,
domain: token.domain as string,
companyId: token.companyId as number,
image: (token as any).imageUrl ?? null
}
}
return session
},
},
}
const handler = NextAuth(authOptions)
export { handler as GET, handler as POST }
|